Added ProtocolHelper and some tests
[brmtron.git] / BrmTron Server / src / cz / brmlab / brmtron / server / BrmTronServer.java
blob8e3f70de50742f248804e69bc4507f2e0cdbb91a
1 package cz.brmlab.brmtron.server;
3 import java.net.ServerSocket;
4 import java.net.Socket;
5 import java.util.LinkedHashMap;
6 import java.util.LinkedList;
7 import java.util.List;
8 import java.util.Map;
10 public class BrmTronServer {
12 private static final int PORT = 4567;
14 static Socket s;
15 private static boolean active = true;
16 private static int threadId = 1;
18 private static List<PathElement> walls = new LinkedList<PathElement>();
20 private static Map<Integer, Player> players = new LinkedHashMap<Integer, Player>();
22 /**
23 * @param args
25 public static void main(String[] args) {
26 ServerSocket srvSock = null;
28 try {
29 srvSock = new ServerSocket(PORT);
30 } catch(Exception e) {
31 System.err.println(e);
32 System.exit(-1);
35 try {
36 while(active) {
37 new BrmTronServerThread(srvSock.accept(), threadId++).start();
39 } catch(Exception e) {
40 System.err.println(e);
44 public static void updatePlayer(int id, Player p) {
45 //FIXME nemusime dostavat kompletni informace, chce to nejak mergovat
46 players.put(id, p);
49 public static Map<Integer, Player> getPlayers() {
50 return players;
53 /**
54 * @param wall Wall to add
55 * Adds new wall to the list of the walls.
57 public static void addWall(PathElement wall) {
58 walls.add(wall);
61 /**
62 * @param p1
63 * @return Coordinates of collision, if exists, otherwise returns null.
64 * Checks given line against internal list of walls for collision.
66 public static double[] checkForCollision(PathElement p1) {
67 //threshold for near-only optimization
68 final double threshold = 5;
70 double[] collisionCoords = null;
71 List<PathElement> brm = new LinkedList<PathElement>();
73 for(PathElement p : walls) {
74 if(isNear(p1, p, threshold))
75 brm.add(p);
78 for(PathElement p2 : brm) {
79 collisionCoords = findIntersection(p1,p2);
80 if(collisionCoords != null)
81 break;
83 return collisionCoords;
86 /**
87 * @param p1 First line to check
88 * @param p2 Second line to check
89 * @param threshold
90 * @return
91 * Determines, if two lines are too far from each other or not.
92 * If start point of line 2 belongs to a square area determined by start point of line 1 and given threshold.
94 private static boolean isNear(PathElement p1, PathElement p2, double threshold) {
95 if(Math.abs(p2.getStart()[0] - p1.getStart()[0]) > threshold ||
96 Math.abs(p2.getStart()[1] - p1.getStart()[1]) > threshold) {
97 return false;
98 } else
99 return true;
103 * @param line1
104 * @param line2
105 * @return Coordinates of intersection, if exists, otherwise returns null.
106 * Finds an intersection of two lines.
108 public static double[] findIntersection(PathElement line1, PathElement line2) {
109 double[] intersection = null;
110 double[] start1 = line1.getStart();
111 double[] end1 = line1.getEnd();
112 double[] start2 = line2.getStart();
113 double[] end2 = line2.getEnd();
115 double x1min = Math.min(start1[0], end1[0]);
116 double x2min = Math.min(start2[0], end2[0]);
117 double x1max = Math.max(start1[0], end1[0]);
118 double x2max = Math.max(start2[0], end2[0]);
119 double y1min = Math.min(start1[1], end1[1]);
120 double y2min = Math.min(start2[1], end2[1]);
121 double y1max = Math.max(start1[1], end1[1]);
122 double y2max = Math.max(start2[1], end2[1]);
124 if((y2min > y1max) || (y2max < y1min) || (x2max < x1min) || (x2min > x1max))
125 return null;
127 if(checkLines(y1min, y2min, y1max, y2max, start1, start2, end1, end2) ||
128 checkLines(y2min, y1min, y2max, y1max, start2, start1, end2, end1))
129 return calcIntersection(line1, line2);
131 return intersection;
135 * @param y1min
136 * @param y2min
137 * @param y1max
138 * @param y2max
139 * @param start1
140 * @param start2
141 * @param end1
142 * @param end2
143 * @return
144 * This method determines, if given lines cross each other or not.
146 protected static boolean checkLines(double y1min, double y2min, double y1max, double y2max, double[] start1, double[] start2, double[] end1, double[] end2) {
147 //FIXME rozbiji se to, pokud jsou nejake souradnice stejne (v praxi se to sice skoro nestane, ale stejne je to fuj)
148 if(y1min <= y2min) {
149 if(y1max < y2min)
150 return false;
152 double d1,d2;
153 double a,b;
155 if(y1min == start1[1]) { //tady se to rozbiji, chce to tu identifikaci bodu vyresit jinak; kdyz jsou y-souradnice stejny, tak je rozbijou rovnice dole
156 a = start1[0];
157 b = end1[0];
158 } else {
159 a = end1[0];
160 b = start1[0];
163 d1 = Math.signum(a - (start2[0]+((end2[0] - start2[0])*(y1min-start2[1]))/(end2[1] - start2[1])));
164 d2 = Math.signum(b - (start2[0]+((end2[0] - start2[0])*(y1max-start2[1]))/(end2[1] - start2[1])));
166 if(d1 == -d2)
167 return true;
169 return false;
173 * @param line1
174 * @param line2
175 * @return Coordinates of intersection.
176 * Finds coordinates of intersection of given lines. This method expects that the intersection exists.
178 protected static double[] calcIntersection(PathElement line1, PathElement line2){
179 double a1, b1, c1, a2, b2, c2, det_inv, m1, m2;
180 double[] ret = new double[2];
182 double x0 = line1.getStart()[0];
183 double y0 = line1.getStart()[1];
184 double x1 = line1.getEnd()[0];
185 double y1 = line1.getEnd()[1];
186 double x2 = line2.getStart()[0];
187 double y2 = line2.getStart()[1];
188 double x3 = line2.getEnd()[0];
189 double y3 = line2.getEnd()[1];
191 if ((x1-x0)!=0)
192 m1 = (y1-y0)/(x1-x0);
193 else
194 m1 = (double)1e+10;
196 if ((x3-x2)!=0)
197 m2 = (y3-y2)/(x3-x2);
198 else
199 m2 = (double)1e+10;
201 a1 = m1;
202 a2 = m2;
204 b1 = -1;
205 b2 = -1;
207 c1 = (y0-m1*x0);
208 c2 = (y2-m2*x2);
210 det_inv = 1/(a1*b2 - a2*b1);
211 ret[0]=((b1*c2 - b2*c1)*det_inv);
212 ret[1]=((a2*c1 - a1*c2)*det_inv);
214 return ret;